package com.yznote.cloudesk.message.service.impl;

import com.yznote.cloudesk.common.constants.YCacheConstant;
import com.yznote.cloudesk.common.constants.YConstant;
import com.yznote.cloudesk.common.exception.YException;
import com.yznote.cloudesk.common.oss.OssUtils;
import com.yznote.cloudesk.common.pojo.*;
import com.yznote.cloudesk.common.tokenShare.YTokenShare;
import com.yznote.cloudesk.common.utils.IdUtils;
import com.yznote.cloudesk.cache.yCache.YCache;
import com.yznote.cloudesk.config.NoticeConfig;
import com.yznote.cloudesk.message.mapper.MessageMapper;
import com.yznote.cloudesk.message.mapper.RoomMapper;
import com.yznote.cloudesk.message.mapper.TempMapper;
import com.yznote.cloudesk.message.service.RoomService;
import com.yznote.cloudesk.user.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import java.text.MessageFormat;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@Transactional
public class RoomServiceImpl implements RoomService {
    @Autowired
    RoomMapper roomMapper;
    @Autowired
    YTokenShare yTokenShare;
    @Autowired
    UserMapper userMapper;
    @Autowired
    NoticeConfig.NoticeUtil noticeUtil;
    @Autowired
    MessageMapper messageMapper;
    @Autowired
    TempMapper tempMapper;
    @Autowired
    OssUtils ossUtils;
    @Autowired
    YCache yCache;


    @Override
    public Room creatRoom(Room room) {
        User user = yTokenShare.get();
        __initRoom(room);
        room.setCreateBy(user.getUserId());
        room.setUpdateBy(user.getUserId());
        room.setRoomOwnerId(user.getUserId());
        Integer i = roomMapper.createRoom(room);
        if (i == 0) return null;
        RoomUser roomUser = __initRoomUser();
        roomUser.setRoomUserStatus(0);
        roomUser.setRoomId(room.getRoomId());
        roomUser.setUserId(room.getRoomOwnerId());
        roomUser.setCreateBy(room.getCreateBy());
        roomUser.setUpdateBy(room.getUpdateBy());
        Integer i1 = roomMapper.createRoomUser(roomUser);
        if (i1 == 0) return null;
        List<User> users = new ArrayList<>();
        User user1 = new User();
        user1.setUserId(user.getUserId());
        user1.setUserName(user.getUserName());
        user1.setLoginTime(user.getLoginTime());
        users.add(user1);
        room.setUsers(users);
        return room;
    }

    @Override
    public List<Room> queryRoomList() {
        User user = yTokenShare.get();
        List<Room> roomList = roomMapper.queryRoomList(user.getUserId());
        // 获得房间的用户列表
        if (roomList == null) return null;
        for (int i = 0; i < roomList.size(); i++) {
            Room room = roomList.get(i);
            room.setUsers(roomMapper.selectUsersInRoom(room.getRoomId()));
            room.setUnread(messageMapper.getOfflineMessageCount(user.getUserId(),room.getRoomId()));
            room.setLastMessage(messageMapper.getLastMessage(room.getRoomId()));
        }
        return roomList;
    }

    @Override
    public Boolean joinRoom(Long roomId) {
        User user = yTokenShare.get();
        // 判断是否存在该房间
        Room room = roomMapper.getRoomById(roomId);
        if (room == null) return false;
        // 加入该房间 之后做房主的同意及相关权限验证;
        LocalDateTime now = LocalDateTime.now();
        RoomUser roomUser = new RoomUser();
        roomUser.setRoomId(roomId);
        roomUser.setRoomUserStatus(0);
        roomUser.setUserId(user.getUserId());
        roomUser.setUpdateTime(now);
        roomUser.setCreateBy(user.getUserId());
        roomUser.setUpdateBy(user.getUserId());
        roomUser.setCreateTime(now);
        roomUser.setLastReadTime(now);
        Integer i = roomMapper.joinRoom(roomUser);
        if (i == 0) return false;
        return true;
    }

    @Override
    public List<Room> queryRoomListByName(String roomName) {
        if (roomName == null) roomName = "";
        return roomMapper.queryRoomListByName(roomName);
    }

    @Override
    public Boolean inviteUserToRoom(Long roomId, Long userId) {
        User user = yTokenShare.get();
        // 获得房间实例
        Room room = roomMapper.getRoomById(roomId);
        // 房间不存在
        if (room == null) return false;
        // 该用户不是房间的主人 返回false
        if (!room.getRoomOwnerId().equals(user.getUserId())) return false;
        RoomUser roomUser = roomMapper.getRoomUserByRoomIdAndUserId(roomId, userId);
        Map meta = new HashMap();
        meta.put("roomId", room.getRoomId());
        if (roomUser == null) {
            // 首次邀请用户进入
            RoomUser roomUser1 = __initRoomUser();
            roomUser1.setUserId(userId);
            roomUser1.setRoomId(roomId);
            roomUser1.setRoomUserStatus(1);
            roomUser1.setCreateBy(user.getUserId());
            roomUser1.setUpdateBy(user.getUserId());
            Integer i = roomMapper.inviteUser(roomUser1);
            if (i == 0) return false;
            noticeUtil.sendNotice(userId, "加入房间邀请", MessageFormat.format(
                    YConstant.INVITE_USER_TEMPLATE,
                    user.getUserName(), room.getRoomName(), room.getRoomId()), meta, 0);
            return true;
        } else if (roomUser.getRoomUserStatus().equals(2) || roomUser.getRoomUserStatus().equals(4)) {
            // 用户之前退出过 用户之前拒绝过
            Integer i = roomMapper.inviteUserTwice(roomId, userId);
            if (i == 0) return false;
            noticeUtil.sendNotice(userId, "加入房间邀请", MessageFormat.format(
                    YConstant.INVITE_USER_TEMPLATE,
                    user.getUserName(), room.getRoomName(), room.getRoomId()), meta, 0);
            return true;
        } else if (roomUser.getRoomUserStatus().equals(3)) {
            // 用户已经申请加入该房间 直接将该用户加入房间
            Integer i = roomMapper.acceptUserToRoom(roomId, userId);
            if (i == 0) return false;
            noticeUtil.sendNotice(userId, "加入房间邀请", MessageFormat.format(
                    "你已加入房间{0}\n房间号:{1}", room.getRoomName(), room.getRoomId()), meta, 0);
            return true;
        }
        // 用户已经被邀请 用户已经进入 或其他异常状态
        return false;
    }

    @Override
    public List<Room> queryInvite() {
        User user = yTokenShare.get();
        List<Room> rooms = roomMapper.queryInvite(user.getUserId());
        return rooms;
    }

    @Override
    public Boolean joinTheRoom(Long roomId) {
        User user = yTokenShare.get();
        // 获得房间实例
        Room room = roomMapper.getRoomById(roomId);
        // 房间不存在
        if (room == null) return false;
        if (room.getRoomOwnerId().equals(user.getUserId())) {
            return false; // 该用户为房间主人 无需申请
        }
        RoomUser roomUser = roomMapper.getRoomUserByRoomIdAndUserId(roomId, user.getUserId());
        if (roomUser.getRoomUserStatus().equals(1)) {
            // 该用户被邀请了 直接进入
            roomMapper.acceptUserToRoom(roomId, user.getUserId());
        } else if (roomUser.getRoomUserStatus().equals(2) || roomUser.getRoomUserStatus().equals(4)) {
            // 该用户退出了该房间 用户拒绝过该申请 重新申请
            Integer i = roomMapper.joinRoomTwice(roomId, user.getUserId());
            if (i == 0) return false;
            return true;
        } else if (roomUser == null) {
            // 从未申请 新增记录
            RoomUser roomUser1 = __initRoomUser();
            roomUser1.setRoomId(roomId);
            roomUser1.setCreateBy(user.getUserId());
            roomUser1.setUpdateBy(user.getUserId());
            roomUser1.setUserId(user.getUserId());
            Integer i = roomMapper.joinTheRoom(roomUser1);
            if (i == 0) return false;
            return true;
        }
        // 用户已经在房间 用户提交过申请 及其他异常状态
        return false;
    }

    @Override
    public List<RoomUser> queryApply() {
        User user = yTokenShare.get();
        List<RoomUser> roomUsers = roomMapper.queryApply(user.getUserId());
        return roomUsers;
    }

    @Override
    public List<RoomUser> queryApplyByRoomId(Long roomId) {
        User user = yTokenShare.get();
        List<RoomUser> roomUsers = roomMapper.queryApplyByRoomId(user.getUserId(), roomId);
        return roomUsers;
    }

    @Override
    public List<User> selectUsersInRoom(Long roomId) {
        User user = yTokenShare.get();
        Room room = roomMapper.getRoomById(roomId);
        if (room == null || !room.getRoomOwnerId().equals(user.getUserId())) return null;
        // 查询
        List<User> users = roomMapper.selectUsersInRoom(roomId);
        return users;
    }

    @Override
    public Boolean acceptRoom(Long roomId) {
        User user = yTokenShare.get();
        Room room = roomMapper.getRoomById(roomId);
        // 房间不存在
        if (room == null) return false;
        RoomUser roomUser = roomMapper.getRoomUserByRoomIdAndUserId(roomId, user.getUserId());
        // 邀请不存在
        if (roomUser == null) return false;
        if (roomUser.getRoomUserStatus().equals(0)) {
            // 已经加入房间
            return true;
        } else if (roomUser.getRoomUserStatus().equals(1)) {
            // 接收
            Integer i = roomMapper.acceptUserToRoom(roomId, user.getUserId());
            if (i != 0) return true;
            return false;
        }
        // 2 已经退出 3 申请进入 4 已经拒绝
        return false;
    }


    @Override
    public List<Message> getOfflineMessage(Long roomId) {
        Long userId = yTokenShare.get().getUserId();
        return messageMapper.getMessagesAfterTimeByUserId(roomId, userId);
    }

    @Override
    public List<Room> getInviteNotice() {
        User user = yTokenShare.get();
        List<Room> roomList = roomMapper.getInviteNotice(user.getUserId());
        return roomList;
    }

    @Override
    public List<Room> getOwnerRoomList() {
        User user = yTokenShare.get();
        List<Room> roomList  = roomMapper.getOwnerRoomList(user.getUserId());
        return roomList;
    }

    @Override
    public Boolean rejectRoom(Long roomId) {
        User user = yTokenShare.get();
        Room room = roomMapper.getRoomById(roomId);
        // 房间不存在
        if (room == null) return false;
        RoomUser roomUser = roomMapper.getRoomUserByRoomIdAndUserId(roomId, user.getUserId());
        // 邀请不存在
        if (roomUser == null) return false;
        if (roomUser.getRoomUserStatus().equals(0)) {
            // 已经加入房间
            return false;
        } else if (roomUser.getRoomUserStatus().equals(1)) {
            // 接收
            Integer i = roomMapper.rejectInvite(roomId, user.getUserId());
            if (i != 0) return true;
            return false;
        } else if(roomUser.getRoomUserStatus().equals(4)){
            return true;
        }
        // 2 已经退出 3 申请进入
        return false;
    }

    @Override
    public Integer getOfflineMessageCount(Long roomId) {
        User user = yTokenShare.get();
        return messageMapper.getOfflineMessageCount(user.getUserId(),roomId);
    }

    @Override
    public Message getLastMessage(Long roomId) {
        User user = yTokenShare.get();
        Message message = messageMapper.getLastMessage(roomId);
        return  message;
    }

    @Override
    public List<Message> getMessages(Long roomId) {
        User user = yTokenShare.get();
        // 判断用户是否在房间中
        RoomUser roomUser = roomMapper.getRoomUserByRoomIdAndUserId(roomId, user.getUserId());
        if(roomUser==null) return null;
        return messageMapper.getRoomMessages(roomId);
    }

    @Override
    public Boolean pushLastTimestamp(LocalDateTime time,Long roomId) {
        User user = yTokenShare.get();
        Integer i = roomMapper.updateReadTime(time,user.getUserId(),roomId);
        if(i==0) return false;
        return true;
    }

    @Override
    public Boolean dismissRoom(Long roomId) {
        User user = yTokenShare.get();
        Integer i = roomMapper.dismissRoom(roomId,user.getUserId());
        if(i==0) return false;
        return true;
    }

    @Override
    public void pushUserHeaders(MultipartFile mtf,Long roomId) throws Exception{
        Long userId = yTokenShare.get().getUserId();
        Room roomById = roomMapper.getRoomById(roomId);
        if (roomById == null){
            throw new YException("当前房间不存在", 500);
        }
        //判断是不是群主
        if (!userId.equals(roomById.getRoomOwnerId())){
                throw new YException("你不是房主，无权设置头像", 500);
        }
        String name =mtf.getOriginalFilename();
        byte[] bytes = mtf.getBytes();
        Long fileId = IdUtils.nextId();
        LocalDateTime now =LocalDateTime.now();
        String path ="filesystem/"+"tempStorage/"+fileId +name.substring(name.lastIndexOf("."));
        //头像存储时间默认为十年
        Long saveTime = (long)60*60*24*30*12*10;
        TempStorage tempStorage = new TempStorage(userId, fileId, (long) -1, 0, roomId, path, saveTime, (long) bytes.length, 0);
        tempStorage.setCreateTime(now);
        tempStorage.setCreateBy(userId);
        tempMapper.insertTemp(tempStorage);
        //存储oss
        ossUtils.pushFileSource(bytes,path);
    }

    @Override
    public void removeUser(Long otherUserId,Long roomId) {
        Long userId = yTokenShare.get().getUserId();
        Room roomById = roomMapper.getRoomById(roomId);
        if (roomById == null){
            throw new YException("当前房间不存在", 500);
        }
        if (!userId.equals(roomById.getRoomOwnerId())){
            throw new YException("你不是房主,无权踢人", 500);
        }
        if (otherUserId.equals(roomById.getRoomOwnerId())){
            throw new YException("你不是能踢掉自己", 500);
        }
        roomMapper.removeUserFromRoom(roomId,userId);
        //删除缓存
        yCache.delayDelete(YCacheConstant.OTHER,roomId.toString());
    }

    @Override
    public void tryJoinRoomByRoomname(String roomName) {

    }

    @Override
    public void tryJoinRoomByRoomId(Long roomId) {
        Long userId = yTokenShare.get().getUserId();
        LocalDateTime now = LocalDateTime.now();
        Room roomById = roomMapper.getRoomById(roomId);
        if (roomById==null){
            throw new YException("没有此房间",500);
        }
        RoomUser roomUser =new RoomUser();
        roomUser.setRoomId(roomId);
        roomUser.setRoomUserStatus(3);
        roomUser.setUserId(userId);
        roomUser.setUpdateBy(userId);
        roomUser.setUpdateBy(userId);
        roomUser.setCreateTime(now);
        roomUser.setLastReadTime(now);
        roomMapper.tryJoinRoom(roomUser);
    }


    private RoomUser __initRoomUser() {
        LocalDateTime now = LocalDateTime.now();
        RoomUser roomUser = new RoomUser();
        roomUser.setUpdateTime(now);
        roomUser.setCreateTime(now);
        roomUser.setLastReadTime(now);
        return roomUser;
    }

    private Room __initRoom() {
        Room room = new Room();
        LocalDateTime now = LocalDateTime.now();
        room.setRoomId(IdUtils.nextId());
        room.setRoomStatus(0);
        room.setCreateTime(now);
        room.setUpdateTime(now);
        return room;
    }

    private void __initRoom(Room room) {
        LocalDateTime now = LocalDateTime.now();
        room.setRoomId(IdUtils.nextId());
        room.setRoomStatus(0);
        room.setCreateTime(now);
        room.setUpdateTime(now);
    }


}
